package srcTA;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import lib.ArgumentValidator;

/**
 * Representation of a Data fed into the system
 * @author abhip
 *
 */
public class InputData
{
    private static void PopulateRankData(InputData inputData) 
    {
        for (Bid bid : inputData.Bids())
        {
            // linearly map cost per region to range 0 to 1
            double cprRange = inputData.maxCostPerRegion - inputData.minCostPerRegion;
            double normalizedCPR =  (bid.CostPerRegion() - inputData.minCostPerRegion)/cprRange;

            bid.setRank(normalizedCPR);
        }
    }

    public static InputData ReadDataFromFile(File file) throws IOException
    {
        ArgumentValidator.IsNotNull("file", file);

        BufferedReader br = new BufferedReader(new FileReader(file));

        String line = null;

        while ((line = br.readLine()) != null)
        {
            line = line.trim();
            if (line.length() > 0)
            {
                break;
            }
        }
        double timeThreshold = Double.parseDouble(line);

        while ((line = br.readLine()) != null)
        {
            line = line.trim();
            if (line.length() > 0)
            {
                break;
            }
        }
        int numRegions = Integer.parseInt(line);

        while ((line = br.readLine()) != null)
        {
            line = line.trim();
            if (line.length() > 0)
            {
                break;
            }
        }
        int numBids = Integer.parseInt(line);

        while ((line = br.readLine()) != null)
        {
            line = line.trim();
            if (line.length() > 0)
            {
                break;
            }
        }
        int numCompanies = Integer.parseInt(line);

        // read bids
        List<Bid> bids =new ArrayList<Bid>();
        int bidCount = 0;
        double maxCostPerRegion = 0;
        double minCostPerRegion = 0;

        while ((line = br.readLine()) != null)
        {
            line = line.trim();

            if (line.endsWith("#"))
            {
                String[] splits = line.split(" ");
                int company = Integer.parseInt(splits[0]);
                double value = Double.parseDouble(splits[1]);
                
                List<Integer> regions = new ArrayList<Integer>();
                for (int i = 2; i < splits.length - 1; ++i)
                {
                    regions.add(Integer.parseInt(splits[i]));
                }

                bids.add(new Bid(bidCount, company, value, regions));
                bidCount++;
                double curCostPerRegion = value/regions.size();
                if (minCostPerRegion == 0 || minCostPerRegion > curCostPerRegion)
                {
                    minCostPerRegion = curCostPerRegion;
                }
                
                if (maxCostPerRegion == 0 || maxCostPerRegion < curCostPerRegion)
                {
                    maxCostPerRegion = curCostPerRegion;
                }
            }
        }

        InputData inputData = new InputData();
        inputData.timeThreshold = timeThreshold;
        inputData.numRegions = numRegions;
        inputData.numBids = numBids;
        inputData.numCompanies = numCompanies;
        inputData.bids = bids;
        inputData.minCostPerRegion = minCostPerRegion;
        inputData.maxCostPerRegion = maxCostPerRegion;

        PopulateRankData(inputData);
        
        return inputData;
    }

    private double timeThreshold;
    private double maxCostPerRegion;
    private double minCostPerRegion;
    private int numRegions;
    private int numBids;
    private int numCompanies;

    private List<Bid> bids;

    /**
     * @return the bids
     */
    public List<Bid> Bids()
    {
        return bids;
    }

    public double MaxCostPerRegion()
    {
        return maxCostPerRegion;
    }

    public double MinCostPerRegion()
    {
        return minCostPerRegion;
    }

    /**
     * @return the numBids
     */
    public int NumBids()
    {
        return numBids;
    }

    /**
     * @return the numCompanies
     */
    public int NumCompanies()
    {
        return numCompanies;
    }
    
    /**
     * @return the numRegions
     */
    public int NumRegions()
    {
        return numRegions;
    }
    
    /**
     * @return the timeThreshold
     */
    public double TimeThreshold()
    {
        return timeThreshold;
    }
}
